home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
-
- #include "bmpout.h"
-
- // Convert the color format to a count of bits.
- static WORD get_color_bits(const BITMAP& bmp)
- {
- WORD color_bits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
-
- if(color_bits == 1) { color_bits = 1; }
- else if(color_bits <= 4) { color_bits = 4; }
- else if(color_bits <= 8) { color_bits = 8; }
- else if(color_bits <= 16) { color_bits = 16; }
- else if(color_bits <= 24) { color_bits = 24; }
- else { color_bits = 32; }
-
- return color_bits;
- }
-
- #include "record.h"
-
- static PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)
- {
- BITMAP bmp;
- PBITMAPINFO pbmi;
- WORD cClrBits;
-
- // Retrieve the bitmap's color format, width, and height.
-
- if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) {
- // error!
- }
-
- #if 0
- REC << "LONG bmType: " << bmp.bmType << "\n";
- REC << "LONG bmWidth: " << bmp.bmWidth << "\n";
- REC << "LONG bmHeight: " << bmp.bmHeight << "\n";
- REC << "LONG bmWidthBytes: " << bmp.bmWidthBytes << "\n";
- REC << "WORD bmPlanes: " << bmp.bmPlanes << "\n";
- REC << "WORD bmBitsPixel: " << bmp.bmBitsPixel << "\n";
- REC << "LPVOID bmBits: " << (int)bmp.bmBits << "\n";
- #endif
-
- // Convert the color format to a count of bits.
-
- cClrBits = get_color_bits(bmp);
-
- // Allocate memory for the BITMAPINFO structure. (This structure
- // contains a BITMAPINFOHEADER structure and an array of RGBQUAD data
- // structures.)
-
- if (cClrBits != 24) {
- size_t size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 ^ cClrBits);
- pbmi = (PBITMAPINFO)malloc(size);
- memset(pbmi, size, 0); // Currently, this has no meaning.
- } else {
- // There is no RGBQUAD array for the 24-bit-per-pixel format.
- size_t size = sizeof(BITMAPINFOHEADER);
- pbmi = (PBITMAPINFO)malloc(size);
- memset(pbmi, size, 0); // Currently, this has no meaning.
- }
-
- /* Initialize the fields in the BITMAPINFO structure. */
-
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmi->bmiHeader.biWidth = bmp.bmWidth;
- pbmi->bmiHeader.biHeight = bmp.bmHeight;
- pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
- pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
-
- // If the bitmap is not compressed, set the BI_RGB flag.
- pbmi->bmiHeader.biCompression = BI_RGB; // If the bitmap is compressed.
-
- // Compute the number of bytes in the array of color
- // indices and store the result in biSizeImage.
- pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 31) / 32 * 4
- * pbmi->bmiHeader.biHeight
- * cClrBits;
-
- pbmi->bmiHeader.biXPelsPerMeter = 0;
- pbmi->bmiHeader.biYPelsPerMeter = 0;
-
- if(cClrBits < 24) {
- pbmi->bmiHeader.biClrUsed = 1 << cClrBits;
- } else {
- pbmi->bmiHeader.biClrUsed = 0;
- }
-
- #if 0
- REC << "pbmi->bmiHeader.biClrUsed: " << pbmi->bmiHeader.biClrUsed << "\n";
- #endif
-
- // Set biClrImportant to 0, indicating that all of the
- // device colors are important.
- pbmi->bmiHeader.biClrImportant = 0;
-
- return pbmi;
- }
-
- // The following example code defines a function that
- // initializes the remaining structures, retrieves the array
- // of palette indices, opens the file, copies the data, and
- // closes the file.
-
- static void make_bitmapfileheader(PBITMAPFILEHEADER hdr, const PBITMAPINFOHEADER pbih)
- {
- hdr->bfType = 0x4d42; /* 0x42 = "B" 0x4d = "M" */
-
- // Compute the size of the entire file.
-
- hdr->bfSize = (DWORD)(sizeof(BITMAPFILEHEADER)
- + pbih->biSize
- + pbih->biClrUsed * sizeof(RGBQUAD)
- + pbih->biSizeImage);
-
- hdr->bfReserved1 = 0;
- hdr->bfReserved2 = 0;
-
- // Compute the offset to the array of color indices.
-
- hdr->bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER)
- + pbih->biSize
- + pbih->biClrUsed * sizeof(RGBQUAD));
- }
-
- #define MAXWRITE 16384
-
- void CreateBMPFile(FILE_NEW& fp, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC)
- {
- BITMAPFILEHEADER hdr; // bitmap file-header
- PBITMAPINFOHEADER pbih; // bitmap info-header
- LPBYTE lpBits; // memory pointer
- DWORD cb; // incremental count of bytes
- BYTE* hp; // byte pointer
-
- pbih = (PBITMAPINFOHEADER) pbi;
- lpBits = (LPBYTE)malloc(pbih->biSizeImage * 2);
-
- if(!lpBits) {
- // error!
- }
-
- // Retrieve the color table (RGBQUAD array) and the bits
- // (array of palette indices) from the DIB.
-
- #if 0
- REC << "pih->biClrUsed: " << pbih->biClrUsed << "\n";
- #endif
-
- if(!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight,
- lpBits, pbi, DIB_RGB_COLORS)) {
- // error!
- }
-
- #if 0
- REC << "pih->biClrUsed: " << pbih->biClrUsed << "\n";
- #endif
-
- #if 1
- pbih->biClrUsed = 2;
- #endif
-
- make_bitmapfileheader(&hdr, pbih);
-
- // Copy the BITMAPFILEHEADER into the .BMP file.
-
- fp.write((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1);
-
- // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
-
- #if 0
- REC << "pih->biClrUsed: " << pbih->biClrUsed << "\n";
- #endif
-
- #if 1
- RGBQUAD white = { 0, 0, 0};
- RGBQUAD black = {255, 255, 255};
- pbi->bmiColors[0] = white;
- pbi->bmiColors[1] = black;
- #endif
-
- fp.write((LPVOID)pbih,
- sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof(RGBQUAD), 1);
-
- // Copy the array of color indices into the .BMP file.
-
- // dwTotal = cb = pbih->biSizeImage;
- cb = pbih->biSizeImage;
- hp = lpBits;
- while(cb > MAXWRITE) {
- fp.write((LPSTR)hp, (size_t)MAXWRITE, 1);
- cb -= MAXWRITE;
- hp += MAXWRITE;
- }
- fp.write((LPSTR)hp, (int)cb, 1);
-
- // Free memory.
-
- free(lpBits);
- }
-
- void OutputBMPFile(FILE_NEW& fp, HBITMAP hBMP, HDC hDC)
- {
- PBITMAPINFO pbmi;
- pbmi = CreateBitmapInfoStruct(hBMP);
- CreateBMPFile(fp, pbmi, hBMP, hDC);
- free(pbmi);
- }
-